package com.waming.spring.sensitive.plugin.json.serializer;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.waming.spring.sensitive.plugin.annotation.SensitiveField;
import com.waming.spring.sensitive.plugin.strategy.SensitiveType;
import com.waming.spring.sensitive.plugin.strategy.SensitiveTypeRegisty;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.util.Objects;

/**
 * @Copyright (c) 合思商城研发团队 https://www.ekuaibao.com
 * @Author: wangmi wangmi@hosecloud.com
 * @Date: 2023/10/26 16:23
 * @Version 1.0
 */
public class SensitiveHandler extends JsonSerializer<String> implements ContextualSerializer {
    private static final Logger LOG = LogManager.getLogger(SensitiveHandler.class);
    /**
     * 脱敏类型
     */
    private SensitiveType type;
    public SensitiveHandler() {
        super();
    }
    public SensitiveHandler(final SensitiveType type) {
        this.type = type;
    }

    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        try {
            if(type!=null){
                gen.writeString(SensitiveTypeRegisty.get(type).handle(value));
            }else{
                gen.writeString(value);
            }
        } catch (Exception e) {
            LOG.error("脱敏失败 => {}", e.getMessage());
            gen.writeString(value);
        }
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov,BeanProperty property) throws
            JsonMappingException {
        //空跳过
        if(property==null){
            return prov.findNullValueSerializer(property);
        }
        //非String类直接跳过
        if (Objects.equals(property.getType().getRawClass(), String.class)) {
            SensitiveHandler sensitiveHandlr = getSensitiveHandler(property);
            if (sensitiveHandlr != null){
                return sensitiveHandlr;
            }
        }
        return prov.findValueSerializer(property.getType(), property);
    }

    private SensitiveHandler getSensitiveHandler(BeanProperty property) {
        SensitiveField annotation = property.getAnnotation(SensitiveField.class);
        if (annotation == null) {
            annotation = property.getContextAnnotation(SensitiveField.class);
        }
        if (annotation != null) {
            // 如果能得到注解，就将注解的 value 传入 MaskSerialize
            return new SensitiveHandler(annotation.value());
        }
        return null;
    }

}
